import { Utils } from "./utils";


interface HttpClientConfig {
    /** 默认头部 */
    header?: { [key: string]: string },
    /** 请求基地址 */
    base?: string,
    /** mock 请求基地址 */
    mockBase?: string,
    /** 初始化钩子 */
    init?: (httpClient: HttpClient) => void,

}

interface HttpClientParams {
    /**
     * 请求描述，必填，方便后期调试
     */
    title?: string,
    /**
     * 请求方法
     */
    method?: | 'get' | 'GET' | 'post' | 'POST',
    /**
     * 请求地址
     */
    url?: string,
    /**
     * 请求地址
     */
    uri?: string,
    /**
     * get 参数
     */
    params?: { [key: string]: string | number } | null,
    /**
     * post 参数
     */
    data?: { [key: string]: any } | null,
    /**
     * 请求头部设置
     */
    header?: { [key: string]: string },
    /**
     * 请求超时时间，单位毫秒
     */
    timeout?: number,
    /**
     * 是否防抖
     */
    isDebounce?: boolean,
    /**
     * 是否缓存数据
     */
    isCachable?: boolean,
    /**
     * 缓存时间(秒)
     */
    cacheDuration?: number,
    /**
     * 是否 loading
     */
    isLoading?: boolean,
    /**
     * loading 显示文字
     */
    loadingText?: string,
    /**
     * 是否请求测试数据
     */
    isMock?: boolean,
    /**
     * 测试数据请求地址
     */
    mockUrl?: string,
    /**
     * 测试数据请求地址
     */
    mockUri?: string,
    /**
     * header 中携带token开关
     */
    withHeaderToken?: boolean,
    /**
     * 默认返回数据，出错时返回
     */
    dafaultResponse?: any,
    /** 延迟 */
    debounce?: number,
}

const HTTP_PARAMS: HttpClientParams = {
    title: '',
    // 请求地址
    url: '',
    // 请求地址
    uri: '',
    // 请求方法
    method: 'GET',
    // get 参数
    params: null,
    // post 参数
    data: null,
    // 请求头部设置
    header: {},
    // 请求超时时间，单位毫秒
    timeout: 300000,
    // 是否防抖 boolean
    isDebounce: false,
    // 是否缓存数据
    isCachable: false,
    // 缓存时间(秒)
    cacheDuration: 8640000,
    // 是否 loading
    isLoading: false,
    // loading 显示文字
    loadingText: '数据处理中...',
    // 是否请求测试数据
    isMock: false,
    // 测试数据请求地址
    mockUrl: '',
    dafaultResponse: {},
    withHeaderToken: true,
    /** 延迟 */
    debounce: 0,
};

/** 网络请求 */
export class HttpClient {
    private _config: HttpClientConfig;

    /** 请求头部 */
    public header: { [key: string]: string } = {};
    /** 请求 base */
    private _base: string = '';
    /** 请求 mockBase */
    private _mockBase: string = '';

    /** 初始化 */
    constructor(config: HttpClientConfig) {
        this._config = config;
        this.header = this._config.header || {};
        this._base = this._config.base || '';
        this._mockBase = config.mockBase || '';
        if (Utils.isFunction(config.init)) {
            config.init!(this);
        }
    }
    /** 处理请求参数 */

    /** 发出请求 
     * @example
     *  const http = new DaUtils.HttpClient({
            base: 'https://e.aidingyi.cn/',
            header: { 'Content-Type': 'application/json' },
            init: (httpClient) => {
                httpClient.header = { ...httpClient.header, ...{ 'Api-Authorize-Token': localStorage.getItem('token') ?? '' } }
            }
        });
        const res: any = await http.request({
            title: `请求列表`,
            uri: `module_listing`,
            method: 'POST',
            data: { module, ...param },
            debounce: 0,
        });
    */
    public request = async (params: HttpClientParams): Promise<any> => {
        /** 默认赋值 */
        const p = { ...Utils.clone(HTTP_PARAMS), ...params };
        /** 请求头部 */
        this.header = { ...this.header, ...p.header };
        /** 请求方式 */
        const method = (p.method + '').toUpperCase();
        /** 请求地址 */
        let url = '';

        /** 是否为开发环境 */
        const isDevEnv = params.isMock && process.env.NODE_ENV === 'development';
        if (isDevEnv) {
            let mockUrl = '';
            if (params.mockUrl) {
                mockUrl = params.mockUrl;
            } else {
                mockUrl = `${this._mockBase}${params.mockUri}`
            }
            url = mockUrl;
        } else {
            if (params.uri) {
                url = `${this._base}${p.uri}`;
            }
            if (params.url) {
                url = `${p.url}`;
            }
        }
        /** 请求数据 */
        let data: any = '';
        if (method === 'POST') {
            data = JSON.stringify(params.data);
            // data = Utils.param(params.data!);
        }
        if (method === 'GET') {
            data = JSON.stringify(params.params);
        }

        return new Promise((resolve, _reject) => {
            let status: number | null = null;
            fetch(url, {
                method,
                headers: this.header,
                // mode:'cors', 
                body: data,
            }).then(response => {
                status = response.status;
                if (status === 200) {
                    return response.json()
                } else {
                    resolve(params.dafaultResponse);
                }
            }).then((responseData: any) => {
                resolve(responseData);
            }).catch((error) => {
                console.log(error);
                resolve(params.dafaultResponse);
            });
        });
    };
}